
using System;

namespace ICommonLibrary.Date {

    public sealed class YearMonthSpan : IComparableDate {

        public int Years {
            get { return _years; }
            set {
                SetYears(value);
            }
        }

        public int Months {
            get { return _months; }
            set {
                SetMonths(value);
            }
        }
        
	    private int _years;
	    private int _months;
	    private int _ym;

	    public YearMonthSpan(int years, int months) {
		    _years = years;
		    _months = months;
		    Normalise();
	    }

	    public YearMonthSpan Clone() {
		    return new YearMonthSpan(_years, _months);
	    }

	    public int GetYears() {
		    return _years;
	    }

	    public void SetYears(int years) {
		    _years = years;
		    Normalise();
	    }

	    public int GetMonths() {
		    return _months;
	    }

	    public void SetMonths(int months) {
		    _months = months;
		    Normalise();
	    }
    	
	    public int GetTotalMonth() {
		    return _ym;
	    }

        public bool Before(MutableDate date) {
            MutableDate refDate = Resolve(DateTime.Now);
            return refDate.Before(date);
        }

        public bool After(MutableDate date) {
            MutableDate refDate = Resolve(DateTime.Now);
            return refDate.After(date);
        }

        public MutableDate Resolve(DateTime baseDate) {
            return new MutableDate(
                baseDate.Year + _years, 
                baseDate.Month + _months - 1, // convert 1-12 to 0-11
                baseDate.Day
            );
        }
    	
	    private void Normalise() {
		    if (_months > 11) {
			    _years += _months / 12;
			    _months = _months % 12;
		    }
		    _ym = _years * 12 + _months;
	    }

        public override int GetHashCode() {
            return _ym;
        }

        public override bool Equals(object o) {
		    if (o == this) {
			    return true;
		    }
		    if (o != null && o.GetType() == typeof(YearMonthSpan)) {
			    var span = (YearMonthSpan) o;
			    return 	_years == span._years && 
					    _months == span._months;
		    }
		    return false;
	    }
        
    }
}